// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   NativeArray.java

package keel.gfx;

import backstage.gfx.DXNativeArray;

import java.lang.reflect.Array;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import java.security.AccessController;
import java.security.PrivilegedAction;

import javax.media.opengl.GL;
import javax.media.opengl.GL2ES2;
import javax.media.opengl.GL2GL3;

import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.util.GLBuffers;

public class NativeArray
{

    public NativeArray(byte array[], boolean isUnsigned)
    {
        type = 0;
        size = 0;
        version = 0;
        if(array == null)
        {
            throw new NullPointerException();
        }
        
        type = isUnsigned ? GL.GL_UNSIGNED_BYTE : GL.GL_BYTE;
        size = array.length;
        buf = Buffers.newDirectByteBuffer(array);
        //buf = GLBuffers.newDirectGLBuffer(type, size);
    }

    public NativeArray(byte array[])
    {
        this(array, false);
    }

    public NativeArray(short array[], boolean isUnsigned)
    {
        type = 0;
        size = 0;
        version = 0;
        if(array == null)
        {
            throw new NullPointerException();
        } 

        type = isUnsigned ? GL.GL_UNSIGNED_SHORT : GL.GL_SHORT;
        size = array.length;
        buf = Buffers.newDirectByteBuffer(getByteCount());
        
        ShortBuffer tbuf = buf.asShortBuffer();
        tbuf.put(array);
    }

    public NativeArray(short array[])
    {
        this(array, false);
    }

    public NativeArray(int array[], boolean isUnsigned)
    {
        type = 0;
        size = 0;
        version = 0;
        if(array == null)
        {
            throw new NullPointerException();
        }
        type = isUnsigned ? GL.GL_UNSIGNED_INT : GL2ES2.GL_INT;
        size = array.length;
        buf = Buffers.newDirectByteBuffer(getByteCount());
        
        IntBuffer tbuf = buf.asIntBuffer();
        tbuf.put(array);
    }

    public NativeArray(int array[])
    {
        this(array, false);
    }

    public NativeArray(float array[])
    {
        type = 0;
        size = 0;
        version = 0;
        if(array == null)
        {
            throw new NullPointerException();
        }
        type = GL.GL_FLOAT;
        size = array.length;
        buf = Buffers.newDirectByteBuffer(getByteCount());
        
        FloatBuffer tbuf = buf.asFloatBuffer();
        tbuf.put(array);
    }

    public NativeArray(double array[])
    {
        type = 0;
        size = 0;
        version = 0;
        if(array == null)
        {
            throw new NullPointerException();
        }
        type = GL2GL3.GL_DOUBLE;
        size = array.length;
        buf = Buffers.newDirectByteBuffer(getByteCount());
        
        DoubleBuffer tbuf = buf.asDoubleBuffer();
        tbuf.put(array);
    }

    public NativeArray(int type, int size)
    {
        this.type = 0;
        this.size = 0;
        version = 0;
        switch(type)
        {
        case 5127: 
        case 5128: 
        case 5129: 
        default:
            throw new IllegalArgumentException();

        case 5120: 
        case 5121: 
        case 5122: 
        case 5123: 
        case 5124: 
        case 5125: 
        case 5126: 
        case 5130: 
            this.type = type;
            break;
        }
        this.size = size;
        buf = Buffers.newDirectByteBuffer(getByteCount());
    }

    public int getType()
    {
        return type;
    }

    public int getSize()
    {
        return size;
    }

    public int getVersion()
    {
        return version;
    }
    
    public int getByteCount()
    {
    	return size*GLBuffers.sizeOfGLType(type);
//        switch(type)
//        {
//        case 5120: 
//        case 5121: 
//            return size;
//
//        case 5122: 
//        case 5123: 
//            return size * 2;
//
//        case 5124: 
//        case 5125: 
//        case 5126: 
//            return size * 4;
//
//        case 5130: 
//            return size * 8;
//
//        case 5127: 
//        case 5128: 
//        case 5129: 
//        default:
//            throw new IllegalStateException();
//        }
    }
    
    public Buffer getBuffer()
    {
    	return buf;
    }
    
    public long getNativePointer()
    {
    	if(buf==null )return 0;
        return Buffers.getDirectBufferByteOffset(buf);
    }

    public static void arraycopy(NativeArray src, int srcoffset, NativeArray dst, int dstoffset, int length)
    {
        int t = getTypeSize(src.type);
        if(t == -1 || t != getTypeSize(dst.type))
            throw new IllegalArgumentException("Incompatible array type");
        if(length <= 0)
            return;
        if(srcoffset < 0 || dstoffset < 0 || src.size < length + srcoffset || dst.size < length + dstoffset)
        {
            throw new ArrayIndexOutOfBoundsException();
        } else
        {
        	byte srcArr[] = new byte[src.getByteCount()];
        	byte dstArr[] = new byte[dst.getByteCount()];
     
        	ByteBuffer srcbuf=src.buf.asReadOnlyBuffer();
        	srcbuf.clear();
        	srcbuf.get(srcArr);
        	dst.buf.clear();
        	dst.buf.get(dstArr);
        	System.arraycopy(srcArr, srcoffset * t, dstArr, dstoffset * t, length * t);
        	
        	dst.buf.clear();
        	dst.buf.put(dstArr);
        	
            //_memcpy(src.nativePointer, srcoffset * t, dst.nativePointer, dstoffset * t, length * t);
            dst.version++;
            return;
        }
    }

    private static int getTypeSize(int t)
    {
    	return GLBuffers.sizeOfGLType(t);
//        switch(t)
//        {
//        case 5120: 
//        case 5121: 
//            return 1;
//
//        case 5122: 
//        case 5123: 
//            return 2;
//
//        case 5124: 
//        case 5125: 
//        case 5126: 
//            return 4;
//
//        case 5130: 
//            return 8;
//
//        case 5127: 
//        case 5128: 
//        case 5129: 
//        default:
//            return -1;
//        }
    }

    public void copyToArray(byte array[])
    {
        copyToArray(array, 0, 0, size);
    }

    public void copyToArray(byte array[], int srcoffset, int dstoffset, int length)
    {
        if(type != 5120 && type != 5121)
            throw new IllegalArgumentException("Invalid array type: byte[]");
        if(length <= 0)
            return;
        if(srcoffset < 0 || dstoffset < 0 || array.length < dstoffset + length || size < srcoffset + length)
        {
            throw new ArrayIndexOutOfBoundsException();
        } else
        {
        	ByteBuffer srcbuf=buf.asReadOnlyBuffer();
        	byte srcArr[] = new byte[size];
        	srcbuf.clear();
        	srcbuf.get(srcArr);
        	System.arraycopy(srcArr, srcoffset, array, dstoffset, length);
        	
            //_memcpy(array, nativePointer, srcoffset, dstoffset, length);
            return;
        }
    }

    public void copyToArray(short array[])
    {
        copyToArray(array, 0, 0, size);
    }

    public void copyToArray(short array[], int srcoffset, int dstoffset, int length)
    {
        if(type != 5122 && type != 5123)
            throw new IllegalArgumentException("Invalid array type: short[]");
        if(length <= 0)
            return;
        if(srcoffset < 0 || dstoffset < 0 || array.length < dstoffset + length || size < srcoffset + length)
        {
            throw new ArrayIndexOutOfBoundsException();
        } else
        {
        	ShortBuffer srcbuf=buf.asShortBuffer();
        	short srcArr[] = new short[size];
        	srcbuf.clear();
        	srcbuf.get(srcArr);
        	System.arraycopy(srcArr, srcoffset, array, dstoffset, length);
        	
            //_memcpy(array, nativePointer, srcoffset * 2, dstoffset * 2, length * 2);
            return;
        }
    }

    public void copyToArray(int array[])
    {
        copyToArray(array, 0, 0, size);
    }

    public void copyToArray(int array[], int srcoffset, int dstoffset, int length)
    {
        if(type != 5124 && type != 5125)
            throw new IllegalArgumentException("Invalid array type: int[]");
        if(length <= 0)
            return;
        if(srcoffset < 0 || dstoffset < 0 || array.length < dstoffset + length || size < srcoffset + length)
        {
            throw new ArrayIndexOutOfBoundsException();
        } else
        {
        	IntBuffer srcbuf=buf.asIntBuffer();
        	int srcArr[] = new int[size];
        	srcbuf.clear();
        	srcbuf.get(srcArr);
        	System.arraycopy(srcArr, srcoffset, array, dstoffset, length);
            //_memcpy(array, nativePointer, srcoffset * 4, dstoffset * 4, length * 4);
            return;
        }
    }

    public void copyToArray(float array[])
    {
        copyToArray(array, 0, 0, size);
    }

    public void copyToArray(float array[], int srcoffset, int dstoffset, int length)
    {
        if(type != 5126)
            throw new IllegalArgumentException("Invalid array type: float[]");
        if(length <= 0)
            return;
        if(srcoffset < 0 || dstoffset < 0 || array.length < dstoffset + length || size < srcoffset + length)
        {
            throw new ArrayIndexOutOfBoundsException();
        } else
        {
        	FloatBuffer srcbuf=buf.asFloatBuffer();
        	float srcArr[] = new float[size];
        	srcbuf.clear();
        	srcbuf.get(srcArr);
        	System.arraycopy(srcArr, srcoffset, array, dstoffset, length);
            //_memcpy(array, nativePointer, srcoffset * 4, dstoffset * 4, length * 4);
            return;
        }
    }

    public void copyToArray(double array[])
    {
        copyToArray(array, 0, 0, size);
    }

    public void copyToArray(double array[], int srcoffset, int dstoffset, int length)
    {
        if(type != 5126)
            throw new IllegalArgumentException("Invalid array type: double[]");
        if(length <= 0)
            return;
        if(srcoffset < 0 || dstoffset < 0 || array.length < dstoffset + length || size < srcoffset + length)
        {
            throw new ArrayIndexOutOfBoundsException();
        } else
        {
        	DoubleBuffer srcbuf=buf.asDoubleBuffer();
        	double srcArr[] = new double[size];
        	srcbuf.clear();
        	srcbuf.get(srcArr);
        	System.arraycopy(srcArr, srcoffset, array, dstoffset, length);
            //_memcpy(array, nativePointer, srcoffset * 8, dstoffset * 8, length * 8);
            return;
        }
    }

    public void update(byte array[])
    {
        update(array, 0, 0, array.length);
    }

    public void update(byte array[], int srcoffset, int dstoffset, int length)
    {
        if(type != 5120 && type != 5121)
            throw new IllegalArgumentException("Invalid array type: byte[]");
        if(length <= 0)
            return;
        if(srcoffset < 0 || dstoffset < 0 || size < length + dstoffset || array.length < length + srcoffset)
        {
            throw new ArrayIndexOutOfBoundsException();
        } else
        {
        	byte dstArr[] = new byte[size];
        	buf.clear();
        	buf.get(dstArr);
        	System.arraycopy(array, srcoffset , dstArr, dstoffset , length);
        	
        	buf.clear();
        	buf.put(dstArr);
        	
            //_memcpy(nativePointer, array, srcoffset, dstoffset, length);
            version++;
            return;
        }
    }

    public void update(short array[])
    {
        update(array, 0, 0, array.length);
    }

    public void update(short array[], int srcoffset, int dstoffset, int length)
    {
        if(type != 5122 && type != 5123)
            throw new IllegalArgumentException("Invalid array type: short[]");
        if(length <= 0)
            return;
        if(srcoffset < 0 || dstoffset < 0 || size < length + dstoffset || array.length < length + srcoffset)
        {
            throw new ArrayIndexOutOfBoundsException();
        } else
        {
        	ShortBuffer tbuf = buf.asShortBuffer();
        	short dstArr[] = new short[size];
        	tbuf.clear();
        	tbuf.get(dstArr);
        	System.arraycopy(array, srcoffset , dstArr, dstoffset , length);
        	
        	tbuf.clear();
        	tbuf.put(dstArr);
        	
            //_memcpy(nativePointer, array, srcoffset * 2, dstoffset * 2, length * 2);
            version++;
            return;
        }
    }

    public void update(int array[])
    {
        update(array, 0, 0, array.length);
    }

    public void update(int array[], int srcoffset, int dstoffset, int length)
    {
        if(type != 5124 && type != 5125)
            throw new IllegalArgumentException("Invalid array type: int[]");
        if(length <= 0)
            return;
        if(srcoffset < 0 || dstoffset < 0 || size < length + dstoffset || array.length < length + srcoffset)
        {
            throw new ArrayIndexOutOfBoundsException();
        } else
        {
        	IntBuffer tbuf = buf.asIntBuffer();
        	int dstArr[] = new int[size];
        	tbuf.clear();
        	tbuf.get(dstArr);
        	System.arraycopy(array, srcoffset , dstArr, dstoffset , length);
        	
        	tbuf.clear();
        	tbuf.put(dstArr);
        	
            //_memcpy(nativePointer, array, srcoffset * 4, dstoffset * 4, length * 4);
            version++;
            return;
        }
    }

    public void update(float array[])
    {
        update(array, 0, 0, array.length);
    }

    public void update(float array[], int srcoffset, int dstoffset, int length)
    {
        if(type != 5126)
            throw new IllegalArgumentException("Invalid array type: float[]");
        if(length <= 0)
            return;
        if(srcoffset < 0 || dstoffset < 0 || size < length + dstoffset || array.length < length + srcoffset)
        {
            throw new ArrayIndexOutOfBoundsException();
        } else
        {
        	FloatBuffer tbuf = buf.asFloatBuffer();
        	float dstArr[] = new float[size];
        	tbuf.clear();
        	tbuf.get(dstArr);
        	System.arraycopy(array, srcoffset , dstArr, dstoffset , length);
        	
        	tbuf.clear();
        	tbuf.put(dstArr);
        	
            //_memcpy(nativePointer, array, srcoffset * 4, dstoffset * 4, length * 4);
            version++;
            return;
        }
    }

    public void update(double array[])
    {
        update(array, 0, 0, array.length);
    }

    public void update(double array[], int srcoffset, int dstoffset, int length)
    {
        if(type != 5130)
            throw new IllegalArgumentException("Invalid array type: double[]");
        if(length <= 0)
            return;
        if(srcoffset < 0 || dstoffset < 0 || size < length + dstoffset || array.length < length + srcoffset)
        {
            throw new ArrayIndexOutOfBoundsException();
        } else
        {
        	DoubleBuffer tbuf = buf.asDoubleBuffer();
        	double dstArr[] = new double[size];
        	tbuf.clear();
        	tbuf.get(dstArr);
        	System.arraycopy(array, srcoffset , dstArr, dstoffset , length);
        	
        	tbuf.clear();
        	tbuf.put(dstArr);
        	
            //_memcpy(nativePointer, array, srcoffset * 8, dstoffset * 8, length * 8);
            version++;
            return;
        }
    }

    public String toString()
    {
        return getClass() + " type:" + type + " size:" + size + " ptr:" + getNativePointer();
    }

//    private final native long newNativeArray(int i, Object obj);
//
//    private final native long newNativeArray(int i, int j);
//
//    private static final synchronized native void deleteNativeArray(long l);
//
//    private final native void memcpy(long l, Object obj, int i, int j, int k);
//
//    private final native void memcpy(Object obj, long l, int i, int j, int k);
//    
//    private static final native void memcpy(long l, int i, long l1, int j, int k);
//
    static final void compact(boolean flag){}

//    private final long _newNativeArray(int type, Object o)
//    {
//        return isDX ? DXNativeArray.newNativeArray(type, o) : newNativeArray(type, o);
//    }
//
//    private final long _newNativeArray(int type, int size)
//    {
//        return isDX ? DXNativeArray.newNativeArray(type, size) : newNativeArray(type, size);
//    }
//
//    private static final synchronized void _deleteNativeArray(long pt)
//    {
//        if(isDX)
//            DXNativeArray.deleteNativeArray(pt);
//        else
//            deleteNativeArray(pt);
//    }
//
//    private final void _memcpy(long dstptr, Object srcarray, int srcoffset, int dstoffset, int length)
//    {
//        if(isDX)
//            DXNativeArray.memcpy(dstptr, srcarray, srcoffset, dstoffset, length);
//        else
//            memcpy(dstptr, srcarray, srcoffset, dstoffset, length);
//    }
//
//    private final void _memcpy(Object dstarray, long srcptr, int srcoffset, int dstoffset, int length)
//    {
//        if(isDX)
//            DXNativeArray.memcpy(dstarray, srcptr, srcoffset, dstoffset, length);
//        else
//            memcpy(dstarray, srcptr, srcoffset, dstoffset, length);
//    }
//
//    private static final void _memcpy(long src, int srcoffset, long dst, int dstoffset, int length)
//    {
//        if(isDX)
//            DXNativeArray.memcpy(src, srcoffset, dst, dstoffset, length);
//        else
//            memcpy(src, srcoffset, dst, dstoffset, length);
//    }

    int type;
    private int size;
    int version;
    ByteBuffer buf;
}
